"""VisitorSheet service for business logic (Synchronous)."""

from __future__ import annotations

from typing import Any, Optional
from datetime import date

from ..repositories.visitor_sheet_repository import VisitorSheetRepository
from ..schemas.visitor_sheet import (
    VisitorSheetCreate,
    VisitorSheetUpdate,
    VisitorSheetOut,
    VisitorSheetWithDetails,
)


class VisitorSheetService:
    """Service for visitor sheet management business logic (Synchronous)."""

    def __init__(self, visitor_sheet_repo: VisitorSheetRepository):
        """Initialize service with visitor sheet repository."""
        self.repo = visitor_sheet_repo

    def create_visitor_sheet(self, visitor_sheet_data: VisitorSheetCreate) -> VisitorSheetOut:
        """
        Create a new visitor sheet.

        Args:
            visitor_sheet_data: Visitor sheet creation data

        Returns:
            Created visitor sheet with ID
        """
        db_visitor_sheet = self.repo.create(visitor_sheet_data)
        return VisitorSheetOut.model_validate(db_visitor_sheet)

    def get_visitor_sheet(
        self, visitor_sheet_id: int, with_details: bool = False
    ) -> Optional[VisitorSheetOut | VisitorSheetWithDetails]:
        """
        Get visitor sheet by ID.

        Args:
            visitor_sheet_id: Visitor sheet ID
            with_details: Whether to include related entity details

        Returns:
            Visitor sheet if found, None otherwise
        """
        if with_details:
            db_visitor_sheet = self.repo.get_with_details(visitor_sheet_id)
            if not db_visitor_sheet:
                return None

            # Build response with details
            visitor_dict = VisitorSheetOut.model_validate(db_visitor_sheet).model_dump()
            visitor_dict.update(
                {
                    "lead_name": db_visitor_sheet.lead.name if db_visitor_sheet.lead else None,
                    "lead_phone": db_visitor_sheet.lead.phone if db_visitor_sheet.lead else None,
                    "property_address": (
                        db_visitor_sheet.property.address if db_visitor_sheet.property else None
                    ),
                    "agent_name": (
                        db_visitor_sheet.agent.full_name or db_visitor_sheet.agent.email
                        if db_visitor_sheet.agent
                        else None
                    ),
                }
            )
            return VisitorSheetWithDetails(**visitor_dict)

        db_visitor_sheet = self.repo.get(visitor_sheet_id)
        if not db_visitor_sheet:
            return None

        return VisitorSheetOut.model_validate(db_visitor_sheet)

    def get_visitor_sheets(
        self,
        skip: int = 0,
        limit: int = 20,
        lead_id: Optional[int] = None,
        property_id: Optional[int] = None,
        agent_id: Optional[int] = None,
        start_date: Optional[date] = None,
        end_date: Optional[date] = None,
        intention: Optional[str] = None,
    ) -> tuple[list[VisitorSheetOut], int]:
        """
        Get paginated list of visitor sheets with filters.

        Args:
            skip: Number of records to skip
            limit: Maximum number of records to return
            lead_id: Filter by lead ID
            property_id: Filter by property ID
            agent_id: Filter by agent ID
            start_date: Filter by visit date >= start_date
            end_date: Filter by visit date <= end_date
            intention: Filter by intention level

        Returns:
            Tuple of (visitor sheet list, total count)
        """
        visitor_sheets, total = self.repo.get_by_criteria(
            skip=skip,
            limit=limit,
            lead_id=lead_id,
            property_id=property_id,
            agent_id=agent_id,
            start_date=start_date,
            end_date=end_date,
            intention=intention,
        )

        return [VisitorSheetOut.model_validate(vs) for vs in visitor_sheets], total

    def update_visitor_sheet(
        self, visitor_sheet_id: int, visitor_sheet_data: VisitorSheetUpdate
    ) -> Optional[VisitorSheetOut]:
        """
        Update visitor sheet by ID.

        Args:
            visitor_sheet_id: Visitor sheet ID
            visitor_sheet_data: Visitor sheet update data

        Returns:
            Updated visitor sheet if found, None otherwise
        """
        db_visitor_sheet = self.repo.get(visitor_sheet_id)
        if not db_visitor_sheet:
            return None

        updated_visitor_sheet = self.repo.update(db_visitor_sheet, visitor_sheet_data)
        return VisitorSheetOut.model_validate(updated_visitor_sheet)

    def delete_visitor_sheet(self, visitor_sheet_id: int) -> bool:
        """
        Delete visitor sheet by ID.

        Args:
            visitor_sheet_id: Visitor sheet ID

        Returns:
            True if deleted, False if not found
        """
        return self.repo.delete(visitor_sheet_id)

    def get_satisfaction_stats(
        self, property_id: Optional[int] = None, agent_id: Optional[int] = None
    ) -> dict[str, Any]:
        """
        Get satisfaction statistics.

        Args:
            property_id: Filter by property ID
            agent_id: Filter by agent ID

        Returns:
            Dictionary with satisfaction stats
        """
        return self.repo.get_satisfaction_stats(property_id=property_id, agent_id=agent_id)
